题目说明
1 | 给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。 |
解题思路一
- 首先要理解这个题。这道题明显还是跟
前缀有关系的东西,毫无疑问肯定又需要用到动态规划保存状态。 - 我们先来看子字符串中的各元音字母的个数,题目呢,要求的是
偶数次,那么我们的a,e,i,o,u的出现次数是不是可以转化为出现次数的奇偶性呢?即nums % 2 === 1 是奇数次nums % 2 === 0 是偶数次
那么我们的
a,e,i,o,u的各自状态就只有两种情况啦,0 or 1,例如1
2
3
4
5'a': 0,
'e': 0,
'o': 1,
'i': 0,
'u': 0那我们现在用二进制来表示一下它:
00100, 那么类似于这样的表示有几种情况呢?2 x 2 x 2 x 2 x 2 = 32仅仅只有32种情况,就可以完全表示元音字母的所有状态了。那么我们声明一个长度为32的status数组,值都初始化为-1。- 按照正常思维,符合条件的情况有两种子字符串,一是
从头开始的,一个是从中间开始的。- 从头开始的很容易理解(假设首位下标为
0,i),只要从0到i,状态为00000就可以了。代表都是偶数次出现。 - 从中间开始的话(假设首位下标为
j,i),是从j到i这个子字符串的状态为00000 - 那什么情况下子字符串的状态可以是00000呢? 那当然是i,j各自的状态一致的时候,因为同状态互减才会为0,例如
01000 - 01000 = 00000 - so,01000在字串中是会出现多次的,因为
2%2 == 0, 4%2===0状态也是会重复的,所以我们想求出这个状态之间的最大间距,就要记录该状态最早出现的下标。
- 从头开始的很容易理解(假设首位下标为
- 好了,理解了这个状态之后,我们明确了我们要记录的值,记录该位置的状态下的最早下标。
- 我们是不是可以记录一下,从
第1个字母开始到第i个字母之间的各元音状态呢? - 例如:
"eleetminicoworoep"对应的状态数组[01000,01000,00000,01000,01000,01000,01100...] i 为 0,1,3,4,5的时候状态都一致,那么我们只需要记录status[8] = 0,取最小值即可。- 所以
status数组记录的是32种状态各自在字符串中最早出现的下标 - 最后我们遍历字符串,求出每一位的
状态key(例如01000),根据这个key和下标i,我们去status里面找key的最小下标status[key],然后用i - status[key]求出距离长度。若status[key]为-1,则将下标i赋值给status[key] = i
代码实现一
1 | /** |